<template>
    <div>
        <el-form label-width="80px" :inline="false" size="normal" :rules="rules" :model="spuForm" class="demo-ruleForm">
            <el-form-item label="SPU名称" size="small" prop="spuName">
                <el-input placeholder="SPU名称" v-model="spuForm.spuName"></el-input>
            </el-form-item>
            <el-form-item label="品牌" size="small" prop="tmId">
                <el-select placeholder="请选择" clearable @change="" v-model="spuForm.tmId">
                    <el-option :label="item.tmName" :value="item.id" v-for="item in trademarkList"
                        :key="item.id"></el-option>
                </el-select>
            </el-form-item>
            <el-form-item label="SPU描述" size="small" prop="description">
                <el-input type="textarea" :rows="4" placeholder="SPU描述" v-model="spuForm.description">
                </el-input>
            </el-form-item>
            <el-form-item label="SPU图片" prop="spuImageList">
                <el-upload :action="`${baseUrl}/admin/product/upload`" list-type="picture-card"
                    :file-list="spuForm.spuImageList" :on-preview="handlePictureCardPreview" :on-remove="handleRemove"
                    :on-success="handleLoad">
                    <i class="el-icon-plus"></i>
                </el-upload>
                <el-dialog :visible.sync="dialogVisible">
                    <img width="100%" :src="dialogImageUrl" alt="">
                </el-dialog>
            </el-form-item>
            <el-form-item label="销售属性">
                <el-select v-model="saleAttrName" size="small" :placeholder="`还有${saleAttrLists.length} 未选择`" @change="">
                    <el-option :value="item.name" v-for="item in saleAttrLists" :key="item.id"></el-option>
                </el-select>
                <el-button type="primary" size="small" @click="addSaleAttrValue" icon="el-icon-plus"
                    :disabled="!saleAttrName">添加销售属性</el-button>
            </el-form-item>
            <el-form-item>
                <el-table border stripe :data="spuForm.spuSaleAttrList">
                    <el-table-column type="index" align="center" width="80" label="序号"></el-table-column>
                    <el-table-column width="150" label="属性名" prop="saleAttrName"></el-table-column>
                    <el-table-column label="属性值名称列表">
                        <template v-slot="{ row, cloumn, $index }">
                            <el-tag :key="item.id" v-for="(item, index) in row.spuSaleAttrValueList" closable
                                :disable-transitions="false" @close="deleteAttrValue(row, index)" size="mini">
                                {{
                                    item.saleAttrValueName }}
                            </el-tag>
                            <el-input class="input-new-tag" v-show="row.isChecked" v-model="row.AttrValueName"
                                ref="saveTagInput" size="mini" @keyup.enter.native="handleInputConfirm(row)"
                                @blur="handleInputConfirm(row)">
                            </el-input>
                            <el-button v-show="!row.isChecked" class="button-new-tag" size="small"
                                @click="showInput(row)">添加
                                +</el-button>
                        </template>
                    </el-table-column>
                    <el-table-column width="150" label="操作">
                        <template v-slot="{ row, cloumn, $index }">
                            <el-button type="danger" size="mini" @click="delteAttr($index)"
                                icon="el-icon-delete"></el-button>
                        </template>
                    </el-table-column>
                </el-table>
            </el-form-item>
            <el-form-item>
                <el-button type="primary" size="small" @click="saveSpuForm"
                    :disabled="!spuForm.spuSaleAttrList.length > 0">保存</el-button>
                <el-button size="small" @click="notSave">取消</el-button>

            </el-form-item>
        </el-form>

    </div>
</template>

<script>
import spuApi from '@/api/spu'
import skuApi from '@/api/sku'
import { cloneDeep } from 'lodash'
export default {
    name: 'spuForm',
    props: ['spu', 'isShowSpu'],
    data() {
        return {
            dialogImageUrl: '',// 使用url的地址
            dialogVisible: false,// 预览图片
            spuForm: { ...this.spu, spuImageList: [], spuSaleAttrList: [] },
            spuImageList: [],// 收集图片列表
            tmName: '',
            spuSaleAttrList: [],// 收集销售属性列表
            baseUrl: process.env.VUE_APP_BASE_API,// 配置请求前缀
            saleAttrValueList: [],// 销售属性值列表,暂时保存
            saleAttrName: '',// 用来展示的销售数据
            trademarkList: [], // 品牌列表
            inputVisible: false,
            rules: {
                spuName: [
                    { required: true, message: '请输入SPU名称' },
                    { min: 2, max: 15, message: '长度在 2 到 15 个字符', trigger: 'change' }
                ],
                tmId: [
                    { required: true, message: '必须选择一个品牌', trigger: 'change' }
                ],
                description: [
                    { required: true, message: '品牌描述是必填的！', trigger: 'blur' }
                ],
                spuImageList: [
                    { required: true, message: '至少要有一张图片', trigger: 'change' }
                ],
            }
        };
    },
    methods: {
        // 删除图片
        handleRemove(file, fileList) {
            console.log(file, fileList);
            // 第二个参数是我们的图片列表，每次删除或者是上传都会重新返回一个新数组
            this.spuForm.spuImageList = fileList
        },
        // 预览图片
        handlePictureCardPreview(file) {
            this.dialogImageUrl = file.url;
            this.dialogVisible = true;
        },
        // 图片上传成功
        handleLoad(response, file, fileList) {
            // console.log(response, file, fileList);
            // 第三个参数是我们的图片列表，每次删除或者是上传都会重新返回一个新数组
            this.spuForm.spuImageList = fileList
        },
        // 获取销售属性列表
        async getSaleAttrList() {
            const res = await spuApi.getBaseSaleAttrList()
            if (res.code) {
                this.spuSaleAttrList = res.data
            }
        },
        // 获取品牌列表
        async getTrademarkList() {
            const res = await spuApi.getTrademarkList()
            if (res.code) {
                this.trademarkList = res.data
            }
        },
        // 获取图片列表
        async getImgList() {
            if (this.spu.id) {
                const res = await skuApi.getSpuImageList(this.spu.id)
                // console.log(res.data);
                if (res.code === 200) {
                    this.spuForm.spuImageList = res.data?.map(item => {
                        return {
                            ...item,
                            name: item.imgName,
                            url: item.imgUrl
                        }
                    })
                }
            }
        },
        // 点击取消 然后退出添加页面
        notSave() {
            this.isShowSpu({ val: '1' })
        },
        // 根据点击修改的当前spuid发送请求获取对应的销售属性
        async getSpuSaleAttr() {
            if (this.spu.id) {
                const res = await skuApi.getSpuSaleAttrList(this.spu.id)
                // console.log(res);
                this.spuForm.spuSaleAttrList = res.data

            }
        },
        // 添加销售属性
        addSaleAttrValue() {
            // 根据saleAttrName去找对应的数据，然后添加到下面的表格中
            let attrName = this.saleAttrName
            // 根据收集的名字去找到对应的数据
            let item = this.spuSaleAttrList.find(i => i.name === attrName)
            // 根据数据去整理一份对象
            let obj = {
                baseSaleAttrId: item.id,
                spuId: this.spuForm.id,
                spuSaleAttrValueList: [],
                saleAttrName: item.name
            }
                // 虽然vue2直接添加的数据不是响应，但是push是不影响的
                ; this.spuForm.spuSaleAttrList.push(obj)
            // vue2的修改非响应式是作用于引用类型，简单数据类型是不受影响的
            this.saleAttrName = ''
        },
        // 删除销售属性值
        deleteAttrValue(row, index) {
            row.spuSaleAttrValueList.splice(index, 1)
        },
        // 删除销售属性
        delteAttr(index) {
            this.$confirm('此操作将删除这个销售属性, 是否删除?', '删除销售属性', {
                confirmButtonText: '确定',
                cancelButtonText: '取消',
                type: 'warning'
            }).then(() => {
                this.$message({
                    type: 'success',
                    message: '删除成功!'
                });
                this.spuForm.spuSaleAttrList.splice(index, 1)
            }).catch(() => {
                this.$message({
                    type: 'info',
                    message: '已取消删除'
                });
            });

        },
        // 控制销售属性值value的输入框是否显示和获取焦点
        showInput(row) {
            this.$set(row, 'isChecked', true)
            this.$nextTick(_ => {
                this.$refs.saveTagInput.$refs.input.focus();
            });
        },
        // 值已经确定 回车或者离开焦点
        handleInputConfirm(row) {
            // 判断是否有值
            if (row.AttrValueName) {
                // 定义需要的值
                let obj = {
                    saleAttrValueName: row.AttrValueName,
                    baseSaleAttrId: row.baseSaleAttrId,
                }
                // 使用定义的值进行push到属性值列表中
                row.spuSaleAttrValueList.push(obj)
                // 清空输入框和返回按钮模式
                row.AttrValueName = ''
                // row.isChecked = false
                this.$set(row, 'isChecked', false)
            } else {// 为空
                // 为空不让他进行，直接就弹回去
                row.AttrValueName = ''
                // row.isChecked = false
                this.$set(row, 'isChecked', false)
                return
            }
        },
        // 点击保存
        async saveSpuForm() {
            // 使用深拷贝，因为直接复制会影响到渲染的数据，所以使用深拷贝
            let spuInfo = cloneDeep(this.spuForm)
            // 因为我们添加的数据，在第一层会多attrValueName和isChecked，所以需要使用map，根据数据去过滤掉不要的数据
            spuInfo.spuSaleAttrList = spuInfo.spuSaleAttrList.map(item => {
                return {
                    baseSaleAttrId: item.baseSaleAttrId,
                    saleAttrName: item.saleAttrName,
                    spuSaleAttrValueList: item.spuSaleAttrValueList,
                }
            })
            // 图片列表
            spuInfo.spuImageList = spuInfo.spuImageList.map(item => {
                return {
                    spuId: spuInfo.id,
                    // 进行或  因为后面添加的图片 都会有 name  但是不一样的imgName  所以或   如果有imgName就继续用 没有就用name
                    imgName: item.imgName || item.name,
                    // 我们如果添加了图片，存放在最外层的是一个本地地址，但是里面response中的data是网络地址
                    imgUrl: item.imgUrl || item.response.data,
                    uid: Date.now()
                }
            })
            // console.log(spuInfo);
            try {
                // 发送请求保存，并且返回之前spuList
                await spuApi.saveSpuInfo(spuInfo)
                await this.isShowSpu({ val: '1' })
                // 提示
                this.$message.success(`${this.spuForm.id ? '修改' : '添加'}成功`)
            } catch (error) {
                this.$message.error(`${this.spuForm.id ? '修改' : '添加'}失败`)
            }
        }
    },
    async mounted() {
        await this.getImgList()
        await this.getSaleAttrList()
        await this.getTrademarkList()
        await this.getSpuSaleAttr()
    },
    computed: {
        // 根据我们获取到的销售属性和修改的spu自带的销售进行返回出来
        saleAttrLists() {
            // console.log(this.spuForm.spuSaleAttrList, this.spuSaleAttrList);
            // 遍历一遍我们的数据去查找原数据   如果如果名字相同说明有相同的  我们需要将不相同的返回来就可以了
            let val = this.spuSaleAttrList.filter(item => {
                return this.spuForm.spuSaleAttrList.every(i => i.saleAttrName !== item.name)
            })
            return val
        }
    }
}
</script>

<style scoped>
.el-tag+.el-tag {
    margin-left: 10px;
}

.button-new-tag {
    margin-left: 10px;
    height: 32px;
    line-height: 30px;
    padding-top: 0;
    padding-bottom: 0;
}

.input-new-tag {
    width: 90px;
    margin-left: 10px;
    vertical-align: bottom;
}
</style>
